﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using CodeCamp.BL;
using CodeCamp.BL.Helpers;
using CodeCamp.BL.Model;
using CodeCamp.BL.UI;
using System.Linq;

namespace CodeCamp.Web.Controllers
{
	public class SessionController : CodeCampController
	{
		private const int MAX_IMAGE_SIZE = 640000;

		private readonly char[] TAG_SEPARATORS = new[] { ',', '|', ':', ';' };

		private readonly string[] ALLOWED_FILE_TYPES = new[]
		                                      	{
		                                      		"application/application/zip",
		                                      		"application/vnd.ms-powerpoint",
		                                      		"application/vnd.openxmlformats-officedocument.presentationml.presentation",
		                                      		"application/x-7z-compressed",
		                                      		"text/plain"
		                                      	};

		[MvcMenuItem("Sessions", Order = 10)]
		public ActionResult Index()
		{
			IEnumerable<SessionDetail> sessions = CodeCampBL.ListSessions();
			return View("Index", sessions);
		}

		[MvcMenuItem("Tracks", Order = 20, ParentLink = "/Session/Index")]
		public ActionResult Track(string id)
		{
			var sessions = CodeCampBL.ListByTrack(id, "Unassigned");
			return View(sessions);
		}


		[MvcMenuItem("Add Session", ParentLink = "/Session/Index", Order = 1)]
		[Authorize]
		public ActionResult Add()
		{
			if (CodeCampBL.GetMemberProfile(GetUserID()) == null)
			{
				ModelState.AddModelError(
					"MemberProfile",
					"In order to present a session, you must first save a profile and check the 'Allow Public Profile' box.");
			}

			return View(new Session());
		}

		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Add(Session session, string tagList)
		{
			if (ModelState.IsValid)
			{
				try
				{
					Guid userId = GetUserID();
					int sessionID = CodeCampBL.AddSession(session, userId);
					CodeCampBL.SaveTags(sessionID, buildTagList(tagList), userId);
					this.ShowMessage("Your session was added.");
					return RedirectToAction("Index");
				}
				catch (ArgumentException ex)
				{
					ModelState.AddModelError("MemberProfile", ex.Message);
					return View(session);
				}
			}

			ModelState.AddModelError("Session", "Some entries were not valid. Please correct and resubmit.");
			return View(session);
		}


		[Authorize]
		public ActionResult Edit(int id)
		{
			Session session = CodeCampBL.GetSession(id);
			return View(session);
		}

		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Edit(Session session, string tagList)
		{
			if (ModelState.IsValid)
			{
				try
				{
					Guid userId = GetUserID();
					string[] tags = buildTagList(tagList);
					CodeCampBL.EditSession(session, userId);
					CodeCampBL.SaveTags(session.SessionID, tags, userId);

					this.ShowMessage("Session successfully saved.");
				}
				catch (InvalidOperationException ex)
				{
					ModelState.AddModelError("MemberProfile", ex.Message);
					return View(session);
				}

			}
			return View(session);
		}


		public ActionResult Details(int id)
		{
			Session session = CodeCampBL.GetSession(id);
			return View(session);
		}

		[Authorize]
		public ActionResult AddInterest(int id)
		{
			try
			{
				CodeCampBL.AddInterest(GetUserID(), id);
				this.ShowMessage("Your interest has been logged.");
			}
			catch
			{
				this.ShowError("Failed updating interest");
			}
			return Index();
		}

		[Authorize]
		public ActionResult AddPresenter(int id)
		{
			Session data = CodeCampBL.GetSession(id);
			return View(data);
		}

		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult AddPresenter(int SessionID, string CoPresenterEmail)
		{
			bool isAdded = CodeCampBL.AddPresenter(SessionID, CoPresenterEmail);
			if (isAdded)
			{
				return RedirectToAction("Index");
			}
			ModelState.AddModelError("CoPresenterEmail", "Unable to add this presenter");
			return View(CodeCampBL.GetSession(SessionID));
		}


		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult AddFile(int SessionID, HttpPostedFileBase fileAttachment)
		{
			Guid userID = GetUserID();

			if (fileAttachment.IsValidUploadedFile(ALLOWED_FILE_TYPES, MAX_IMAGE_SIZE))
			{
				CodeCampBL.SaveSessionAttachment(fileAttachment, userID, SessionID);
				this.ShowMessage("The file has been added to the session!");
			}
			else
			{
				ModelState.AddModelError("fileAttachment", "Invalid file type or file too large");
			}


			return View("Edit", CodeCampBL.GetSession(SessionID));
		}

		private string[] buildTagList(string tagList)
		{
			return (tagList ?? string.Empty).Split(TAG_SEPARATORS, StringSplitOptions.RemoveEmptyEntries);
		}

	}
}